home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / misc1 / 20bfiles.zip / ANSWER.XWS < prev    next >
Text File  |  1993-03-05  |  30KB  |  1,361 lines

  1. /*
  2.     Crosstalk for Windows Answer Mode Script
  3.  
  4.     This script provides an unattended 'answer mode' to answer outside calls.  
  5.     The NetID is used by this script to limit callers to a specific directory.  
  6.  
  7.     Copyright (C) 1989, 1993 Digital Communications Associates, Inc.
  8.     All Rights Reserved.
  9.  
  10.     For Version 2.0  06-08-92 KMP
  11.  
  12.     Version 00    01-19-93 PJL    - General fixes
  13.     Version 01    02-03-93 PJL    - More fixes
  14.     Version 02    03-05-93 PJL    - Script Cancel, Error on Go fixes
  15. */
  16.  
  17.     ScriptDesc "Answer calls"
  18.  
  19.     include "SERVFUNC.XWS"
  20.  
  21.     assume device "DCAMODEM.PRE"
  22.     assume protocol "DCAXYMDM.PRE"
  23.     assume terminal "DCATTY.PRE"
  24.  
  25.  
  26. /***************************************************************************
  27.  
  28.     This script accomplishes two things:
  29.  
  30.         1)    Setup a phone book entry (ANSWER.XWP) for answer mode.  When run
  31.             offline against a phone book entry with Patience set to 10, this
  32.             script assumes that this phone book has not been configured and
  33.             will ask the user several questions including login passwords, 
  34.             directory access restrictions and caller activity     restrictions.
  35.  
  36.     ***        NOTE:    To reconfigure ANSWER.XWP, set "Seconds to allow host
  37.                     to answer" value, in Settings.Connection dialog, to 10.
  38.  
  39.         2)    After a connection has been established the users (both remote
  40.             and local) get a menu (a la Crosstalk Mk.4/Communicator 2.1) of
  41.             things to do.  The current directory is automatically set to either
  42.             the DownloadDir (session setting) or DirFil (workstation setting).
  43.  
  44. ****************************************************************************
  45.  
  46.     USER DEFINABLE VARIABLES:
  47.     -------------------------
  48.  
  49.     Change the following variables for your requirements:
  50.  
  51.     1) string "Accept"
  52.  
  53.         The file access level for the caller, works like Crosstalk Mk.4's
  54.         Accept variable.
  55.  
  56.         Valid values for this string are:
  57.  
  58.         "All"        - Allow all accesses.  Read, Write, Create, etc.
  59.         "Append"        - Allows only appending to existing files.  Cannot
  60.                       create     new files.
  61.         "Create"        - Allows only creation of new files.  Cannot overwrite
  62.                       or erase old files.
  63.         "None"        - Allows no uploading, only downloading.
  64.  
  65.     2) Settings.Session "NetID" variable:
  66.  
  67.         If this value contains the string "DirRestrict", then callers are
  68.         restricted to the current download directory.  The Settings.Session
  69.         "DownloadDir" directory is used; if this variable is empty, then the
  70.         Settings.Workstation "DirFil" directory is used.
  71.  
  72. ***************************************************************************/
  73.  
  74.  
  75. /*
  76.     USER DEFINABLE VARIABLE DECLARATIONS & INITIALIZATIONS
  77. */
  78.  
  79.     string Accept
  80.  
  81.     Accept = "All"            -- default
  82.  
  83.  
  84. /*
  85.     INTERNAL VARIABLE DECLARATIONS/INITIALIZATIONS - DO NOT CHANGE
  86. */
  87.  
  88.     boolean expert, driveLock, msgFileOpen, callerBye
  89.     string S_Q_C, NEW_STR, USER_NAME, MESSAGE_FILE
  90.     string savDrive, savDir
  91.     
  92.     driveLock = FALSE : msgFileOpen = FALSE
  93.     MESSAGE_FILE = HomeDir + "\ANSWER.MSG"
  94.     S_Q_C = "Press Ctrl-S to pause, Ctrl-Q to resume, Ctrl-C to terminate."
  95.  
  96.  
  97. /*
  98.     PROCEDURE AND FUNCTION DECLARATIONS
  99. */
  100.  
  101.  
  102. proc SET_DRIVE takes string cDrive
  103.  
  104.     if upcase(cDrive) <> upcase(left(curDrive, 1)) then
  105.     {
  106.         drive cDrive
  107.     }
  108.  
  109. endproc
  110.  
  111.  
  112. proc SET_DIRFIL takes boolean fReset
  113.  
  114.     if fReset then
  115.     {
  116.         if not null(savDrive) then SET_DRIVE savDrive
  117.         if not null(savDir) then cd savDir
  118.     }
  119.     else
  120.     {
  121.         savDrive = "" : savDir = ""
  122.  
  123.         if not null(DownloadDir) then
  124.         {
  125.             -- Switch to session download directory, if there is one.
  126.             savDir = curDir
  127.             SET_DRIVE left(DownloadDir, 1)
  128.             cd DownloadDir
  129.         }
  130.         else if not null(DirFil) then
  131.         {
  132.             -- Switch to Workstation DirFil directory, if there is one.
  133.             savDir = curDir
  134.             SET_DRIVE left(DirFil, 1)
  135.             cd DirFil
  136.         }
  137.     }
  138.  
  139. endproc
  140.  
  141.  
  142. /*
  143.     CHECK
  144.     Check for errors and lost connection.  End the script if we get either
  145.     of these recycling to answer more calls.
  146. */
  147.  
  148. proc CHECK
  149.  
  150.     if callerBye then exit
  151.  
  152.     if not Online then {
  153.         wait 5 ticks
  154.         e = error
  155.         bye
  156.         wait 5 ticks
  157.         e = error
  158.         errmsg = 'Lost Connection'
  159.         print
  160.         print errmsg
  161.         print
  162.         capture off
  163.         SET_DIRFIL TRUE        -- Reset original directory.
  164.         chain HomeDir + "\XWP20\ANSWER.XWS"
  165.     }
  166.  
  167.     if error then {
  168.         errmsg = str(errclass) + ' - ' + str(errno)
  169.         if errclass = 13 and errno = 12 then errmsg = 'File(s) not found'
  170.         else if errclass = 20 then errmsg = 'Lost Connection'
  171.         else if errclass = 45 then {
  172.             case errno of
  173.                 1:    errmsg = "General timeout"
  174.                 2:    errmsg = "Host not responding"
  175.                 3:    errmsg = "Bad response from host"
  176.                 4:    errmsg = "Maximum errors exceeded"
  177.                 5:    errmsg = "Transfer cancelled"
  178.                 7:    errmsg = "Transfer cancelled"
  179.                 8:    errmsg = "Transfer cancelled"
  180.                10:    errmsg = "File(s) not found"
  181.                11:    errmsg = "Local disk full"
  182.                12:    errmsg = "Host disk full"
  183.                15:    errmsg = "Local system busy"
  184.                18:    errmsg = "Host BlockSize must be 1,2,3 or 4"
  185.             endcase
  186.         }
  187.  
  188.         errmsg = "Error: " + errmsg
  189.         print
  190.         reply
  191.         print errmsg
  192.         reply errmsg
  193.         print
  194.         reply
  195.     }
  196.  
  197. endproc
  198.  
  199.  
  200. /*
  201.     PRINT_SEND
  202.     Print the string on the screen and send it the host.  Watch for lost
  203.     connection at the same time.  Note that if no SendString is passed in,
  204.     a return is displayed.  Also, a line feed is added to data sent to the
  205.     caller.
  206. */
  207.  
  208. proc    PRINT_SEND takes optional string SendString
  209.  
  210.     print SendString
  211.     CHECK
  212.     reply SendString
  213.     reply chr(10);
  214.     CHECK
  215.  
  216. endproc
  217.  
  218.  
  219. /*
  220.     GET_COMMAND
  221.     Send the menu prompt and get the answer from the user.
  222. */
  223.  
  224. function GET_COMMAND (string P) returns string
  225.  
  226.     string NEW_STR
  227.  
  228.     PRINT_SEND
  229.     CHECK
  230.     PRINT_SEND
  231.     P = P + chr(32)
  232.     print P;
  233.     reply P;
  234.     CHECK
  235.  
  236.     ExitNow = FALSE
  237.     while not ExitNow
  238.         CHECK
  239.         inChar = nextchar
  240.         if not null(inChar) then {
  241.             if inChar = chr(13) then {
  242.                 ExitNow = TRUE
  243.             }
  244.             else if inChar = chr(8) then {
  245.                 if not null(NEW_STR) then {
  246.                     if length(NEW_STR) = 1 then {
  247.                         NEW_STR = ""
  248.                     }
  249.                     else
  250.                     {
  251.                         NEW_STR = left(NEW_STR, length(NEW_STR) - 1)
  252.                     }
  253.                 }
  254.             }
  255.             else {
  256.                 NEW_STR = NEW_STR + inChar
  257.             }
  258.             print inChar;
  259.             reply inChar;
  260.         }
  261.         else {
  262.             UserKey = inkey
  263.             if UserKey <> 0 then {
  264.                 if UserKey = 13 then {
  265.                     ExitNow = TRUE
  266.                 }
  267.                 else if UserKey = 8 then {
  268.                     if not null(NEW_STR) then {
  269.                         if length(NEW_STR) = 1 then {
  270.                             NEW_STR = ""
  271.                         }
  272.                         else
  273.                         {
  274.                             NEW_STR = left(NEW_STR, length(NEW_STR) - 1)
  275.                         }
  276.                     }
  277.                 }
  278.                 else {
  279.                     NEW_STR = NEW_STR + chr(UserKey)
  280.                 }
  281.                 print chr(UserKey);
  282.                 reply chr(UserKey);
  283.             }
  284.         }
  285.     wend
  286.  
  287.     PRINT_SEND
  288.     CHECK
  289.  
  290.     return(NEW_STR)
  291. endfunc
  292.  
  293.  
  294. /*
  295.     PETC
  296.     This proc asks the user to 'press enter to continue'.
  297. */
  298.  
  299. proc PETC
  300.  
  301.     NEW_STR = GET_COMMAND ("Press Enter to continue.")
  302.  
  303. endproc
  304.  
  305.  
  306. /*
  307.     LOCK_NEW_STR
  308.     Forces NEW_STR to be in the locked dir if appropriate.
  309. */
  310.  
  311. proc LOCK_NEW_STR
  312.  
  313.     if driveLock then NEW_STR = DownloadDir
  314.  
  315. endProc
  316.  
  317.  
  318. proc DRIVE_LOCK_CHECK
  319.  
  320.     if not null(DownloadDir) then
  321.     {
  322.         if NetID = "DirRestrict" then driveLock = TRUE
  323.         else driveLock = FALSE
  324.     }
  325.     else driveLock = FALSE
  326.  
  327. endproc
  328.  
  329.  
  330. /*
  331.     CHECK_DRIVE_ERROR
  332.     Check for what drive error and put a message on the screen
  333.     Returns a boolean indicating an error occured.
  334. */
  335.  
  336. func CHECK_DRIVE_ERROR (string FileSpec) returns boolean
  337.  
  338.     x = error
  339.     if not x then return (x)
  340.  
  341.     print "Error: ";
  342.     reply "Error: ";
  343.  
  344.     case errclass of
  345.         16:    {
  346.             case errno of
  347.                 1:    PRINT_SEND "Device is write-protected"
  348.                 3:    PRINT_SEND "Drive not ready"
  349.             default: PRINT_SEND "Unknown error " + str(errclass) + "-" + str(errno)
  350.             endcase
  351.         }
  352.         19:    {
  353.             case errno of
  354.                 2:    PRINT_SEND "File not found - " + FileSpec
  355.                 3:    PRINT_SEND "Path not found - " + FileSpec
  356.                 4:    PRINT_SEND "No file handles left"
  357.                 5:    PRINT_SEND "Access denied to " + FileSpec
  358.                15:    PRINT_SEND "Invalid drive - " + Filespec + ":"
  359.                19:    PRINT_SEND "Diskette is write-protected"
  360.                20:    PRINT_SEND "Can't use DOS device as file"
  361.                22:    PRINT_SEND "Invalid characters in file name"
  362.             default: PRINT_SEND "Unknown error " + str(errclass) + "-" + str(errno)
  363.             endcase
  364.         }
  365.         default:    PRINT_SEND "Unknown error " + str(errclass) + "-" + str(errno)
  366.         endcase
  367.  
  368.     return(x)
  369.  
  370. endfunc
  371.  
  372.  
  373. /*
  374.     DO_FILE_LIST
  375.     This proc lists the files on the screen 4 across.
  376. */
  377.  
  378. proc DO_FILE_LIST takes string FileSpec
  379.  
  380.     integer FileSpacing, SpaceCount, MaxColumn, CurrentColumn, Attributes, nLen
  381.     string FileName, DirName, Fspec, sDir
  382.  
  383.     /* Check for root directory */
  384.     if right(FileSpec, 1) = "\" then {
  385.         FileSpec = FileSpec + "*.*"
  386.     }
  387.     else if right(FileSpec, 1) = ":" then {
  388.         FileSpec = FileSpec + "\*.*"
  389.     }
  390.     else if right(FileSpec, 3) <> "*.*" then {
  391.         if right(FileSpec, 2) <> "*." then {
  392.             Attributes = fileattr(FileSpec,10h) & 10h
  393.             anError = Error
  394.             if Attributes = 10h then {
  395.                 FileSpec = FileSpec + "\*.*"
  396.             }
  397.         }
  398.     }
  399.  
  400.     -- Parse out the directory name.
  401.     DirName = ""
  402.     nLen = length(FileSpec) - 1
  403.     while nLen > 0
  404.         Fspec = mid(FileSpec, nLen, 1)
  405.         if Fspec = "\" then {
  406.             DirName = left(FileSpec, nLen)
  407.             nLen = 0
  408.         }
  409.         else nLen = nLen - 1
  410.     wend
  411.  
  412.     -- If we didn't find one, use the current directory.
  413.     if null(DirName) then {
  414.         DirName = curDrive + curDir
  415.         if right(DirName, 1) <> "\" then {
  416.             FileSpec = DirName + "\" + FileSpec
  417.         }
  418.         else {
  419.             FileSpec = DirName + FileSpec
  420.         }
  421.     }
  422.     else if left(DirName, 1) = "\" then {
  423.         DirName = curDrive + DirName
  424.     }
  425.  
  426.     FileSpacing = 18
  427.     InterSpacing = 6
  428.     nLen = FileSpacing + InterSpacing
  429.     MaxColumn = (80 / nLen) * nLen
  430.     CurrentColumn = 1
  431.     PRINT_SEND
  432.  
  433.     FileName = filefind(FileSpec,10h)
  434.     if null(FileName) then {
  435.         PRINT_SEND "No files found for " + upcase(FileSpec)
  436.         exit
  437.     }
  438.  
  439.     PRINT_SEND
  440.     PRINT_SEND S_Q_C
  441.     PRINT_SEND
  442.  
  443.     wait 1 second
  444.  
  445.     PRINT_SEND "    Directory: " + upcase(FileSpec)
  446.     PRINT_SEND
  447.  
  448.     anError = CHECK_DRIVE_ERROR(FileSpec)
  449.     if anError then exit
  450.  
  451.     while not null(FileName)
  452.  
  453.         while CurrentColumn < MaxColumn and not null(FileName)
  454.  
  455.             -- Parse out the base file name.
  456.             nLen = length(FileName) - 1
  457.             while nLen > 0
  458.                 if mid(FileName, nLen, 1) = "\" then {
  459.                     FileName = right(FileName, length(FileName)-nLen)
  460.                     nLen = 0
  461.                 }
  462.                 else nLen = nLen - 1
  463.             wend
  464.  
  465.             CHECK
  466.             print FileName;
  467.             reply FileName;
  468.  
  469.             NameLength = length(FileName)
  470.  
  471.             if FileName = "." or FileName = ".." then {
  472.                 Attributes = 10h
  473.             }
  474.             else {
  475.                 Fspec = DirName + FileName
  476.                 Attributes = fileattr(Fspec,10h) & 10h
  477.             }
  478.  
  479.             if Attributes = 10h then {
  480.                 SpaceCount = 13 - NameLength
  481.                 sDir = pad("", SpaceCount, " ", 1) + "<DIR>"
  482.                 print sDir;
  483.                 reply sDir;
  484.                 SpaceCount = InterSpacing
  485.             }
  486.             else {
  487.                 SpaceCount = (FileSpacing - NameLength) + InterSpacing
  488.             }
  489.  
  490.             print pad("", SpaceCount, " ", 1);
  491.             reply pad("", SpaceCount, " ", 1);
  492.             CurrentColumn = CurrentColumn + FileSpacing + InterSpacing
  493.  
  494.             FileName = filefind
  495.             anError = CHECK_DRIVE_ERROR(FileName)
  496.             if anError then exit
  497.  
  498.             watch 1 tick for
  499.                 chr(3)    : exit
  500.             endwatch
  501.         wend
  502.  
  503.         PRINT_SEND
  504.         CurrentColumn = 1
  505.     wend
  506.  
  507. endproc
  508.  
  509.  
  510. /*
  511.     UPLOAD_FILE
  512.     Takes a file name as a parameter.  If not there it asks the user to
  513.     enter one.  It then issues the appropriate user instructions for
  514.     the protocol selected and uploads the file.
  515. */
  516.  
  517. proc UPLOAD_FILE takes FNAME
  518.  
  519.     case protocol of
  520.         "DCAXYMDM" :    if upcase(left(ProtoModel,1)) = "X" then flag = 1
  521.                     else flag = 2
  522.         "ZMODEM", ...
  523.         "DCAZMDM"      :    flag = 3
  524.         "DART", ...
  525.         "DCADART"  :    flag = 4
  526.         "XTALK", ...
  527.         "DCAXTALK" :    flag = 5
  528.     endcase
  529.  
  530.     if not null(FNAME) then NEW_STR = FNAME
  531.     else {
  532.         if flag = 1 then {
  533.             PRINT_SEND
  534.             NEW_STR = GET_COMMAND ("Name of file you're uploading to this host?")
  535.             CHECK
  536.             if null(NEW_STR) then exit
  537.         }
  538.     }
  539.  
  540.     CHECK
  541.  
  542.     LOCK_NEW_STR
  543.  
  544.     PRINT_SEND
  545.     case flag of
  546.         1 : PRINT_SEND "Ready for XMODEM upload..."
  547.         2 : PRINT_SEND "Ready for YMODEM upload..."
  548.         3 : PRINT_SEND "Ready for ZMODEM upload..."
  549.         4 : PRINT_SEND "Ready for DART upload..."
  550.         5 : PRINT_SEND "Ready for Crosstalk upload..."
  551.     endcase
  552.     PRINT_SEND "Now give your computer the command to start the transfer."
  553.  
  554.     if flag < 3 then {
  555.         PRINT_SEND
  556.         wait 6 seconds
  557.         if flag = 2 then NEW_STR = ""
  558.         receive NEW_STR
  559.     }
  560.     else {
  561.         PRINT_SEND "Press `^Z to return to the answer menu when transfer completes."
  562.         PRINT_SEND
  563.         done = FALSE
  564.         repeat
  565.             CHECK
  566.             wait 1 tick for "^Z", key 26
  567.             if not timeout then done = TRUE
  568.         until done = TRUE
  569.     }
  570.  
  571. endproc
  572.  
  573.  
  574. /*
  575.     DOWNLOAD_FILE
  576.     Takes a file name as a parameter.  If not there it asks the user to
  577.     enter one.  It then issues the appropriate user instructions for
  578.     the protocol selected and downloads the file.
  579. */
  580.  
  581. proc DOWNLOAD_FILE takes FNAME
  582.  
  583.     case protocol of
  584.         "DCAXYMDM" :    if upcase(left(ProtoModel,1)) = "X" then flag = 1
  585.                       else    flag = 2
  586.         "ZMODEM", ...
  587.         "DCAZMDM"      :    flag = 3
  588.         "DART", ...
  589.         "DCADART"      :    flag = 4
  590.         "XTALK", ...
  591.         "DCAXTALK" :    flag = 5
  592.     endcase
  593.  
  594.     if flag < 4 then {
  595.         if null(FNAME) then {
  596.             PRINT_SEND
  597.             FNAME = GET_COMMAND ("Name of file to download to your computer?")
  598.             if null(FNAME) then exit
  599.         }
  600.     }
  601.  
  602.     CHECK
  603.  
  604.     NEW_STR = ""
  605.     LOCK_NEW_STR
  606.     if not null (NEW_STR) then {
  607.         if instr(FNAME, ':') <> 0 or instr(FNAME, '\') <> 0 then {
  608.             PRINT_SEND
  609.             PRINT_SEND "Access is restricted to the current download directory."
  610.             PRINT_SEND
  611.             exit
  612.         }
  613.         NEW_STR = NEW_STR + "\" + FNAME
  614.     }
  615.     else {
  616.         s = FNAME
  617.         if instr(s, ':') = 0 then {
  618.             if instr(s, '\') = 0 then {
  619.                 NEW_STR = curDrive + curDir
  620.                 if right(NEW_STR, 1) <> '\' then ...
  621.                     NEW_STR = NEW_STR + '\' + s
  622.                 else ...
  623.                     NEW_STR = NEW_STR + s
  624.             }
  625.             else NEW_STR = curdrive + s
  626.         }
  627.         else if instr(s, '\') = 0 then {
  628.             newDir = upcase(left(s, 1))
  629.             savDir = upcase(left(curDir,1))
  630.  
  631.             if newDir <> savDir then {
  632.                 drive newDir
  633.                 NEW_STR = curDrive + curDir
  634.                 drive savDir
  635.                 s = right(s, length(s)-2)
  636.             }
  637.             else NEW_STR = curDrive + curDir
  638.  
  639.             if right(NEW_STR, 1) <> '\' then ...
  640.                 NEW_STR = NEW_STR + '\' + s
  641.             else ...
  642.                 NEW_STR = NEW_STR + s
  643.         }
  644.     }
  645.  
  646.     if (flag < 4) and (not exists(NEW_STR)) then {
  647.         PRINT_SEND
  648.         PRINT_SEND "File not found - "+chr(34)+upcase(NEW_STR)+chr(34)
  649.         PRINT_SEND
  650.         exit
  651.     }
  652.  
  653.     PRINT_SEND
  654.     case flag of
  655.         1 : PRINT_SEND "Ready for XMODEM download..."
  656.         2 : PRINT_SEND "Ready for YMODEM download..."
  657.         3 : PRINT_SEND "Ready for ZMODEM download..."
  658.         4 : PRINT_SEND "Ready for DART download..."
  659.         5 : PRINT_SEND "Ready for Crosstalk download..."
  660.     endcase
  661.     PRINT_SEND "Now give your computer the proper command to effect the transfer."
  662.  
  663.     if flag < 4 then {
  664.         PRINT_SEND
  665.         wait 2 seconds
  666.         send NEW_STR
  667.         if flag = 3 then wait 2 seconds for "OO"
  668.     }
  669.     else
  670.     {
  671.         savDownloadDir = DownloadDir
  672.         DownloadDir = curDrive + curDir
  673.         PRINT_SEND "Press `^Z to return to the answer menu when transfer completes."
  674.         PRINT_SEND
  675.         done = FALSE
  676.         repeat
  677.             CHECK
  678.             wait 1 tick for "^Z", key 26
  679.             if not timeout then done = TRUE
  680.         until done = TRUE
  681.         DownloadDir = savDownloadDir
  682.     }
  683.  
  684. endproc
  685.  
  686.  
  687. proc SELECT_PROTOCOL takes PNAME
  688.  
  689.     case upcase(PNAME) of
  690.         "XTALK", ...
  691.         "DCAXTALK"        : NEW_STR = "1"
  692.         "XMODEM"            : NEW_STR = "2"
  693.         "XMODEM/CRC"        : NEW_STR = "3"
  694.         "XMODEM/1K"        : NEW_STR = "4"
  695.         "XMODEM/G"        : NEW_STR = "5"
  696.         "YMODEM", ...
  697.         "YMODEM/BATCH"    : NEW_STR = "6"
  698.         "YMODEM/G"        : NEW_STR = "7"
  699.         "ZMODEM", ...
  700.         "DCAZMDM"            : NEW_STR = "8"
  701.         "DART", ...
  702.         "DCADART"            : NEW_STR = "9"
  703.         default            : goto ASK_PROTO_NAME
  704.     endcase
  705.     goto SET_PROTO_NAME
  706.  
  707. label ASK_PROTO_NAME
  708.  
  709.     PRINT_SEND
  710.     if Protocol = "DCAXYMDM" then {
  711.         PRINT_SEND "Current protocol is " + ProtoModel
  712.     }
  713.     else if Protocol = "DCAXTALK" then {
  714.         PRINT_SEND "Current protocol is XTALK"
  715.     }
  716.     else {
  717.         PRINT_SEND "Current protocol is " + Protocol
  718.     }
  719.  
  720.     PRINT_SEND
  721.     PRINT_SEND "        1 - Crosstalk"
  722.     PRINT_SEND "        2 - Xmodem"
  723.     PRINT_SEND "        3 - Xmodem/CRC"
  724.     PRINT_SEND "        4 - Xmodem/1K"
  725.     PRINT_SEND "        5 - Xmodem/G"
  726.     PRINT_SEND "        6 - Ymodem/Batch"
  727.     PRINT_SEND "        7 - Ymodem/G"
  728.     PRINT_SEND "        8 - Zmodem"
  729.  
  730.     NEW_STR = GET_COMMAND ("Choose a new protocol:")
  731.  
  732. label SET_PROTO_NAME
  733.  
  734.     case NEW_STR of
  735.         "1":    protocol = "DCAXTALK"
  736.         "2":    protocol = "DCAXYMDM" : ProtoModel = "Xmodem"
  737.         "3":    protocol = "DCAXYMDM" : ProtoModel = "Xmodem/CRC"
  738.         "4":    protocol = "DCAXYMDM" : ProtoModel = "Xmodem/1K"
  739.         "5":    protocol = "DCAXYMDM" : ProtoModel = "Xmodem/G"
  740.         "6":    protocol = "DCAXYMDM" : ProtoModel = "Ymodem/Batch"
  741.         "7":    protocol = "DCAXYMDM" : ProtoModel = "Ymodem/G"
  742.         "8":    protocol = "DCAZMDM"
  743.         "9":    protocol = "DCADART"
  744.         "" :    exit
  745.         default : goto ASK_PROTO_NAME
  746.     endcase
  747.  
  748. endproc
  749.  
  750.  
  751. proc DIR_COMMAND takes FNAME
  752.  
  753.     CHECK
  754.     if null(FNAME) then    {
  755.         FNAME = GET_COMMAND ("Enter file specification:")
  756.         if null(FNAME) then FNAME = curDrive + curDir
  757.     }
  758.     else PRINT_SEND
  759.  
  760.     CHECK
  761.  
  762. -- if we're drive locked, don't allow looking anywhere else.
  763.     NEW_STR = ""
  764.     LOCK_NEW_STR
  765.  
  766.     if not null(NEW_STR) then {
  767.         if instr(FNAME, ":") = 0 and instr(FNAME, "\") = 0 then {
  768.             FNAME = NEW_STR + "\" + FNAME
  769.         }
  770.     }
  771.  
  772.     DO_FILE_LIST FNAME
  773.     PETC
  774.  
  775. endproc
  776.  
  777.  
  778. proc DRIVE_COMMAND takes FNAME        -- but ignores it
  779.  
  780.     PRINT_SEND
  781.     PRINT_SEND "Current drive and directory is " + curDrive + curDir
  782.  
  783.     NEW_STR = GET_COMMAND ("Enter the drive to use:")
  784.     if null(NEW_STR) then NEW_STR = curdrive
  785.     tmpDrive = left(NEW_STR,1)
  786.     drive tmpDrive
  787.     anError = CHECK_DRIVE_ERROR(tmpDrive)
  788.     if anError then exit
  789.  
  790.     NEW_STR = GET_COMMAND ("Enter new directory:")
  791.     if null(NEW_STR) then NEW_STR = curDir
  792.  
  793.     cd NEW_STR
  794.     anError = CHECK_DRIVE_ERROR(NEW_STR)
  795.     if not anError then PRINT_SEND
  796.  
  797. endproc
  798.  
  799.  
  800. /*
  801.     LEAVE_MESSAGE
  802.     Leave a message in the message file.
  803. */
  804.  
  805. proc LEAVE_MESSAGE
  806.  
  807.     integer chMessage
  808.  
  809.     if null(USER_NAME) then {
  810.         NEW_STR = GET_COMMAND("Please enter your name:")
  811.         USER_NAME = NEW_STR
  812.     }
  813.  
  814.     PRINT_SEND
  815.     PRINT_SEND "Please type your message, pressing Enter at the end of each line."
  816.     PRINT_SEND "Press Ctrl-Z to end message."
  817.     PRINT_SEND
  818.  
  819.     CHECK
  820.  
  821.     chMessage = freefile
  822.     open append MESSAGE_FILE as #chMessage
  823.     defoutput = chMessage
  824.  
  825.     write line ""
  826.     write line "%Message ID: " + str(date)
  827.     write line "From: " + USER_NAME
  828.     write line "Date: " + date
  829.     write line "Time: " + strip(time(-1), chr(0), 0)
  830.     write line ""
  831.     
  832.     msgFileOpen = TRUE
  833.     CHECK
  834.  
  835.     IN_STR = ""
  836.     done = FALSE
  837.     while not done
  838.         CHECK
  839.         inChar = nextchar
  840.         while inChar <> ""
  841.             print inChar; : reply inChar;
  842.             case inChar of
  843.                 chr(13):        PRINT_SEND : write line IN_STR : IN_STR = ""
  844.                 chr(8), ...
  845.                 chr(127):        if not null(IN_STR) then
  846.                             {
  847.                                 if length(IN_STR) = 1 then ...
  848.                                     IN_STR = ""
  849.                                 else ...
  850.                                     IN_STR = left(IN_STR, length(IN_STR) - 1)
  851.                             }
  852.                 chr(26):        done = TRUE
  853.                 default:        IN_STR = IN_STR + inChar
  854.             endcase
  855.             CHECK
  856.             inChar = nextchar
  857.         wend
  858.     wend
  859.  
  860.     close #chMessage
  861.     msgFileOpen = FALSE
  862.  
  863. endproc
  864.  
  865.  
  866. proc READ_MESSAGE
  867.  
  868.     if not exists(MESSAGE_FILE) then {
  869.         PRINT_SEND ''
  870.         PRINT_SEND 'No messages on file'
  871.         PRINT_SEND ''
  872.         exit
  873.     }
  874.  
  875.     fn = freefile
  876.     open input MESSAGE_FILE as #fn
  877.     if error then print "Error opening file"
  878.     trash = ""
  879.  
  880.     repeat
  881.         CHECK
  882.         read line #fn, trash
  883.         PRINT_SEND trash
  884. --        wait 1 tick for chr(3), key 3, key 27
  885. --    until eof(fn) = TRUE or timeout = FALSE
  886.     until eof(fn) = TRUE
  887.  
  888.     close #fn
  889.  
  890.     PETC
  891.  
  892. endproc
  893.  
  894.  
  895. proc PAGE_OPERATOR
  896.  
  897.     alarm 3
  898.  
  899.     PRINT_SEND
  900.     PRINT_SEND "Paging operator, please wait ... press Ctrl-Z to abort."
  901.     PRINT_SEND
  902.  
  903.     ctr = 0
  904.     done = FALSE
  905.     repeat
  906.         ctr = ctr + 1
  907.         if ctr => 5 then done = TRUE
  908.         if ctr > 1 then alarm 0
  909.         print ".";
  910.         reply ".";
  911.         watch 5 seconds for
  912.             key 0    : done = TRUE
  913.             chr(26)    : exit
  914.         endwatch
  915.         CHECK
  916.     until done = TRUE
  917.  
  918.     if ctr => 5 then {
  919.         PRINT_SEND
  920.         PRINT_SEND
  921.         PRINT_SEND "Please try again later; the operator is not available."
  922.         PRINT_SEND
  923.         exit
  924.     }
  925.  
  926.     PRINT_SEND
  927.     PRINT_SEND "Just type, pressing Enter at the end of each line."
  928.     PRINT_SEND "Press Ctrl-Z to end chat session."
  929.     PRINT_SEND
  930.  
  931.     IN_STR = ""
  932.     OUT_STR = ""
  933.     done = FALSE
  934.     repeat
  935.         CHECK
  936.         inChar = nextchar
  937.         if inChar <> "" then
  938.         {
  939.             print inChar;
  940.             reply inChar;
  941.             case inChar of
  942.                 chr(13):        PRINT_SEND : IN_STR = ""
  943.                 chr(8), ...
  944.                 chr(127):        if not null(IN_STR) then
  945.                             {
  946.                                 if length(IN_STR) = 1 then ...
  947.                                     IN_STR = ""
  948.                                 else ...
  949.                                     IN_STR = left(IN_STR, length(IN_STR) - 1)
  950.                             }
  951.                 chr(26):        done = TRUE
  952.                 default:        if asc(inChar) > 31 then ...
  953.                                 IN_STR = IN_STR + inChar
  954.             endcase
  955.         }
  956.         else {
  957.             outKey = inkey
  958.             if outKey <> 0 then
  959.             {
  960.                 print chr(outKey);
  961. --                reply chr(outKey);
  962.                 case outKey of
  963.                     13:        PRINT_SEND : OUT_STR = ""
  964.                     8,127:    if not null(OUT_STR) then
  965.                             {
  966.                                 if length(OUT_STR) = 1 then ...
  967.                                     OUT_STR = ""
  968.                                 else ...
  969.                                     OUT_STR = left(OUT_STR, length(OUT_STR) - 1)
  970.                             }
  971.                     26:        done = TRUE
  972.                     default:    if outKey > 31 then ...
  973.                                 OUT_STR = OUT_STR + chr(outKey)
  974.                 endcase
  975.             }
  976.         }
  977.         until done = TRUE
  978.  
  979. endproc
  980.  
  981.  
  982. /*
  983.     ANSWER_MENU
  984.     Put up the online menu and wait for a response
  985. */
  986.  
  987. proc    ANSWER_MENU
  988.  
  989.     string    command_line, command_letter, command_arg, pm, ps
  990.  
  991.     PRINT_SEND
  992.     PRINT_SEND
  993.     PRINT_SEND
  994.  
  995.     PRINT_SEND " Utilities:                             Options:"
  996.  
  997.     PRINT_SEND "         (F)ile directory                       e(X)pert mode on/off"
  998.  
  999.     if driveLock then {
  1000.         PRINT_SEND "         (P)age the host operator               (G)oodbye"
  1001.     }
  1002.     else {
  1003.         PRINT_SEND "         (C)hange Host drive/directory          (G)oodbye"
  1004.  
  1005.         TmpCurDir = curDrive + curDir
  1006.         print "            (now ";
  1007.         reply "            (now ";
  1008.         NumSpaces = 26 - length(TmpCurDir)
  1009.         if NumSpaces >= 0 then {
  1010.             print TmpCurDir + ")";
  1011.             reply TmpCurDir + ")";
  1012.             TheSpaces = pad("",NumSpaces + 3," ",1)
  1013.             print TheSpaces;
  1014.             reply TheSpaces;
  1015.         }
  1016.         else {
  1017.             TmpCurDir = "..." + right(TmpCurDir,26)
  1018.             print TmpCurDir + ")";    
  1019.             reply TmpCurDir + ")";
  1020.         }
  1021.         PRINT_SEND " (P)age the host operator"
  1022.     }
  1023.  
  1024.     PRINT_SEND
  1025.  
  1026.     PRINT_SEND " File Transfers:                        Message functions:"
  1027.  
  1028.     PRINT_SEND "         (D)ownload to your computer            (R)ead messages"
  1029.  
  1030.     if Accept = "All" or Accept = "Append" or Accept = "Create" then {
  1031.         PRINT_SEND "         (U)pload to Host computer              (L)eave a message"
  1032.     }
  1033.  
  1034.     if Protocol = "DCAXYMDM" then {
  1035.         PRINT_SEND "         (S)elect protocol (now " + ProtoModel + ")"
  1036.     }
  1037.     else if Protocol = "DCAXTALK" then {
  1038.         PRINT_SEND "         (S)elect protocol (now XTALK)"
  1039.     }
  1040.     else {
  1041.         PRINT_SEND "         (S)elect protocol (now " + Protocol + ")"
  1042.     }
  1043.     PRINT_SEND
  1044.  
  1045. endproc
  1046.  
  1047.  
  1048. /*
  1049.     ANSWER_COMMAND
  1050.     This proc puts up the command line and waits for a response.
  1051.     It then dispatches the command and returns.
  1052. */
  1053.  
  1054. proc    ANSWER_COMMAND
  1055.  
  1056.     if driveLock then ps = "("
  1057.     else ps = "(C,"
  1058.  
  1059.     case Accept of
  1060.         'All', ...
  1061.         'Append'    : ps = ps + "U,D,L"
  1062.         'Create'    : ps = ps + "U,D"
  1063.         'None'    : ps = ps + "D"
  1064.     endcase
  1065.  
  1066.     ps = ps + ",R,F,P,X,G,S)?"
  1067.  
  1068.     command_line = GET_COMMAND ("Command " + ps)
  1069.     if null(command_line) or ...
  1070.         (length(command_line) > 2 and mid(command_line,2,1) <> chr(32)) then {
  1071.         command_letter = ""
  1072.     }
  1073.     else {
  1074.         command_letter = upcase(left(command_line, 1))
  1075.         command_arg = strip(mid(command_line, instr(command_line + chr(32), chr(32))), 1, 3)
  1076.  
  1077.         ps = strip(ps, 1, 0)
  1078.         ps = strip(ps, "(,?)", 0)
  1079.         ps = upcase(ps) + "H?"
  1080.  
  1081.         if instr(ps, command_letter) = 0 then {
  1082.             command_letter = "XYZZY"
  1083.         }
  1084.     }
  1085.  
  1086.     CHECK
  1087.  
  1088.     case command_letter of
  1089.         "G"        :    PRINT_SEND "Goodbye!" : callerBye = TRUE : wait 2 seconds : bye
  1090.         "X"        :    expert = not expert
  1091.         "L"        :    LEAVE_MESSAGE
  1092.         "R"        :    READ_MESSAGE
  1093.         "U"        :    UPLOAD_FILE command_arg
  1094.         "D"        :    DOWNLOAD_FILE command_arg
  1095.         "F"        :    DIR_COMMAND command_arg
  1096.         "C"        :    DRIVE_COMMAND command_arg
  1097.         "S"        :    SELECT_PROTOCOL command_arg
  1098.         "P"        :    PAGE_OPERATOR
  1099.         "H", "?"    :    expert = FALSE
  1100.         "XYZZY"    : {    PRINT_SEND
  1101.                     PRINT_SEND "That function is not available."
  1102.                     PRINT_SEND
  1103.                   }
  1104.     endcase
  1105.  
  1106. endproc
  1107.  
  1108.  
  1109. /*
  1110.     CHECK_PASSWORD
  1111.     Ask caller for login password.
  1112. */
  1113.  
  1114. function CHECK_PASSWORD returns boolean
  1115.  
  1116.     integer i
  1117.     boolean GotPword
  1118.  
  1119.     if null(Password) then return(TRUE)
  1120.  
  1121.     i = 1
  1122.     GotPword = FALSE
  1123.     while i <= 3 and GotPword = FALSE
  1124.         PRINT_SEND
  1125.         reply "Enter password: ";
  1126.         NEW_STR = nextline(120, Columns)
  1127.         if upcase(NEW_STR) <> upcase(Password) then i = i + 1
  1128.         else GotPword = TRUE
  1129.     wend
  1130.  
  1131.     return(GotPword)
  1132.                     
  1133. endfunc
  1134.  
  1135.  
  1136. /*
  1137.     GET_PASSWORD
  1138.     Ask if they want to password protect the system.
  1139. */
  1140.  
  1141. function GET_PASSWORD returns integer
  1142.  
  1143.     string NewPword
  1144.  
  1145.     DialogBox 50, 50, 256, 95, 'Answer a call'
  1146.         LText           14,  11,  179,  8, "In order to restrict access to your PC, you can require"
  1147.         LText           14,  21,  179,  8, "a password before callers are allowed to connect."
  1148.         LText           14,  31,  179,  8, "Enter the password required for access below, or"
  1149.         LText           14,  41,  179,  8, "leave blank for no password protection."
  1150.         LText           23,  70,   35,  8, "&Password:"
  1151.         EditText       63,  67,  123, 12, Password, NewPword, TABSTOP
  1152.         DefPushButton 207,   9,   40, 14, "OK",    TABSTOP
  1153.         PushButton      207,  28,   40, 14, "Cancel", CANCEL TABSTOP
  1154.     EndDialog    
  1155.  
  1156.     if Choice = 1 then Password    = NewPword
  1157.  
  1158.     return (Choice)
  1159.  
  1160. endfunc
  1161.  
  1162.  
  1163. /*
  1164.     GET_DOWNLOADDIR
  1165.     Ask for the default download directory.
  1166. */
  1167.  
  1168. function GET_DOWNLOADDIR returns integer
  1169.  
  1170.     string NewDownDir
  1171.     
  1172.     DialogBox 50, 50, 261, 80, 'Answer a call'
  1173.         LText           14,  11,  186,  8, "The download directory is the directory to store received"
  1174.         LText           14,  21,  186,  8, "files.  Enter the default directory below, or leave blank"
  1175.         LText           14,  31,  186,  8, "for no default."
  1176.         LText           20,  58,   75,  8, "&Download Directory:"
  1177.         EditText       90,  55,  131, 12, DownloadDir, NewDownDir, TABSTOP
  1178.         DefPushButton 207,   9,   40, 14, "OK",    TABSTOP
  1179.         PushButton      207,  28,   40, 14, "Cancel", CANCEL TABSTOP
  1180.     EndDialog    
  1181.  
  1182.     /* show lock dir */
  1183.     if Choice = 1 then DownloadDir = NewDownDir
  1184.     return (Choice)
  1185.  
  1186. endfunc
  1187.  
  1188.  
  1189. /*
  1190.     GET_LOCK_DIR
  1191.     Ask to lock the directory for transfers to the download dir.
  1192. */
  1193.  
  1194. function GET_LOCK_DIR returns integer
  1195.     
  1196.     DialogBox 50, 50, 256, 59, 'Answer a call'
  1197.         LText           14,  11,  179,  8, "You can restrict callers to the default download"
  1198.         LText           14,  21,  179,  8, "directory, or allow them unrestricted directory access."
  1199.         LText           14,  31,  179,  8, "Do you wish to restrict callers to the default download"
  1200.         LText           14,  41,  179,  8, "directory?"
  1201.         DefPushButton   207,   9,   40, 14, "&Yes",    TABSTOP
  1202.         PushButton      207,  28,   40, 14, "&No", CANCEL TABSTOP
  1203.     EndDialog    
  1204.  
  1205.     /* show lock dir */
  1206.     if Choice = 1 then
  1207.     {
  1208.         NetID = "DirRestrict"
  1209.         DRIVE_LOCK_CHECK
  1210.     }
  1211.     return (Choice)
  1212.  
  1213. endfunc
  1214.  
  1215.  
  1216. /*
  1217.     ANSWER_CONFIG
  1218.     Configures ANSWER.XWP for answer (host) mode.
  1219.     Returns TRUE if configured, FALSE if not.
  1220. */
  1221.  
  1222. function ANSWER_CONFIG returns boolean
  1223.  
  1224.     /* Not configured - ask for service specific info */
  1225.  
  1226.     if not exists(HomeDir + "\NORMAL.XWP") then
  1227.     {
  1228.         alert "Cannot locate Crosstalk directory", OK
  1229.         return(FALSE)
  1230.     }
  1231.     if not exists(HomeDir + "\XWP20\ANSWER.XWP") then
  1232.     {
  1233.         alert "Cannot locate ANSWER.XWP entry", OK
  1234.         return(FALSE)
  1235.     }
  1236.  
  1237.     load HomeDir + "\NORMAL.XWP"
  1238.  
  1239.     savDevice = Device : SavFlow = Flow
  1240.     savPort = Port : savSpeed = Speed
  1241.  
  1242.     load HomeDir + "\XWP20\ANSWER.XWP"
  1243.  
  1244.     Device = savDevice : Flow = SavFlow
  1245.     Port = savPort : Speed = savSpeed
  1246.  
  1247.     TheChoice = GET_PASSWORD
  1248.     if TheChoice <> 1 then
  1249.     {
  1250.         ALERT "Configuration cancelled - open ANSWER.XWP to retry", OK
  1251.         return(FALSE)
  1252.     }
  1253.  
  1254.     TheChoice = GET_DOWNLOADDIR
  1255.     if Choice <> 1 then
  1256.     {
  1257.         ALERT "Configuration cancelled - open ANSWER.XWP to retry", OK
  1258.         return(FALSE)
  1259.     }
  1260.  
  1261.     if not null(DownLoadDir) then
  1262.     {
  1263.         TheChoice = GET_LOCK_DIR
  1264.     }
  1265.  
  1266.     TheChoice = GET_PORT_SPEED ("Answer a call")
  1267.     if TheChoice = 1 then
  1268.     {
  1269.         /* They said OK - show we're configured */
  1270.         Description = "Crosstalk Answer mode"
  1271.         Patience = 60
  1272.         Mode = "Answer"
  1273.         Terminal = "DCATTY"
  1274.         Font = "XT Term"
  1275.         return(TRUE)
  1276.     }
  1277.     else return(FALSE)
  1278.  
  1279. endfunc
  1280.  
  1281.  
  1282. /***************************************************************************
  1283.  
  1284.     MAIN SCRIPT BEGINS HERE
  1285.  
  1286. ***************************************************************************/
  1287.  
  1288.  
  1289.     cls
  1290.     trap on
  1291.  
  1292.  
  1293. /*
  1294.     Check to see if the current phone book entry has been configured yet.
  1295. */
  1296.  
  1297.     if (Patience = 10) then
  1298.     {
  1299.         /* Not configured - ask for service specific info */
  1300.  
  1301.         Configured = ANSWER_CONFIG
  1302.         if not Configured then end
  1303.  
  1304.         save "ANSWER"
  1305.         TheChoice = ASK_CALL_NOW("Answer", "ANSWER")
  1306.         if TheChoice = 2 then end
  1307.     }
  1308.  
  1309.  
  1310. /*
  1311.     Check for Directory restriction, and switch to DownloadDir.
  1312. */
  1313.     DRIVE_LOCK_CHECK
  1314.     SET_DIRFIL FALSE
  1315.  
  1316.  
  1317. /*
  1318.     Wait for the next incoming call (unless session is already online).
  1319. */
  1320.  
  1321.     if not online then {
  1322.         go
  1323.         if error then {
  1324.             errmsg = "Error " + str(ErrClass) + " - " + str(ErrNo)
  1325.             errmsg = errmsg + ".  Unable to establish connection."
  1326.             alert errmsg, OK
  1327.             bye : end
  1328.         }
  1329.         if not online then bye : end
  1330.  
  1331.         /*
  1332.             Allow user to login.
  1333.         */
  1334.         GoodLogin = CHECK_PASSWORD
  1335.         if not GoodLogin then goto RESTART
  1336.     }
  1337.  
  1338.  
  1339. /*
  1340.     Process caller's commands.
  1341. */
  1342.  
  1343.     callerBye = FALSE
  1344.     repeat
  1345.         if not expert then ANSWER_MENU
  1346.         ANSWER_COMMAND
  1347.         CHECK
  1348.     until callerBye = TRUE
  1349.  
  1350.  
  1351. /*
  1352.     Restart the script.
  1353. */
  1354. label RESTART
  1355.     bye
  1356.     SET_DIRFIL TRUE        -- Reset original directory.
  1357.     chain HomeDir + "\XWP20\ANSWER.XWS"
  1358.     end
  1359.  
  1360.  
  1361.